﻿using System.Collections.Generic;
using System.Collections;
namespace System
{
    /// <summary>
    /// 
    /// </summary>
    /// <author>
    /// Tang Jing bo
    /// </author>
    /// <remarks>
    /// Created : 2011-12-1
    /// </remarks>
    public static class DictionaryExtension
    {
        /// <summary>
        /// 扩展调用方法
        /// </summary>
        /// <typeparam name="TKey">The type of the key.</typeparam>
        /// <typeparam name="TValue">The type of the value.</typeparam>
        /// <param name="dictionary">The dictionary.</param>
        /// <param name="key">The key.</param>
        /// <param name="addValue">The add value.</param>
        /// <param name="updateValueFactory">The update value factory.</param>
        /// <returns></returns>
        public static TValue AddOrUpdate<TKey, TValue>(this Dictionary<TKey, TValue> dictionary
            , TKey key, TValue addValue, System.Func<TKey, TValue, TValue> updateValueFactory)
        {
            lock (dictionary)
            {
                TValue v;
                if (dictionary.TryGetValue(key, out v))
                    return dictionary[key] = updateValueFactory(key, v);
                else
                    return dictionary[key] = addValue;
            }
        }

        /// <summary>
        /// 扩展调用方法
        /// </summary>
        /// <typeparam name="TKey">The type of the key.</typeparam>
        /// <typeparam name="TValue">The type of the value.</typeparam>
        /// <param name="dictionary">The dictionary.</param>
        /// <param name="key">The key.</param>
        /// <param name="addValueFactory">The add value factory.</param>
        /// <param name="updateValueFactory">The update value factory.</param>
        /// <returns></returns>
        public static TValue AddOrUpdate<TKey, TValue>(this Dictionary<TKey, TValue> dictionary
          , TKey key, System.Func<TKey, TValue> addValueFactory, System.Func<TKey, TValue, TValue> updateValueFactory)
        {
            lock (dictionary)
            {
                TValue v;
                if (dictionary.TryGetValue(key, out v))
                    return dictionary[key] = updateValueFactory(key, v);
                else
                    return dictionary[key] = addValueFactory(key);
            }
        }

        /// <summary>
        /// 扩展调用方法
        /// </summary>
        /// <typeparam name="TKey">The type of the key.</typeparam>
        /// <typeparam name="TValue">The type of the value.</typeparam>
        /// <param name="dictionary">The dictionary.</param>
        /// <param name="key">The key.</param>
        /// <param name="valueFactory">The value factory.</param>
        /// <returns></returns>
        public static TValue GetOrAdd<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key, System.Func<TKey, TValue> valueFactory)
        {
            lock (dictionary)
            {
                TValue v;
                if (dictionary.TryGetValue(key, out v))
                    return v;
                else
                    return dictionary[key] = valueFactory(key);
            }
        }
        /// <summary>
        /// 扩展调用方法
        /// </summary>
        /// <typeparam name="TKey">The type of the key.</typeparam>
        /// <typeparam name="TValue">The type of the value.</typeparam>
        /// <param name="dictionary">The dictionary.</param>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        public static TValue GetOrAdd<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key, TValue value)
        {
            lock (dictionary)
            {
                TValue v;
                if (dictionary.TryGetValue(key, out v))
                    return v;
                else
                    return dictionary[key] = value;
            }
        }
    }
}